/**
  ******************************************************************************
  * @file    WIFI_Driver.c
  * @author  tuancheng_Zero
  * @version V0.1
  * @date    08/05/2024
  * @brief   WIFI Module Drive
  ******************************************************************************
*/ 
#include <includes.h>
#include "WIFI.h"
#include "WIFI_Driver.h"

//局部变量
static uint8_t curTemArrIndex=0;        // 当前数组下标
//全局变量
uint8_t TemArrRxBuffer[2][DMARxBuffer]; // DMA接收缓冲
uint8_t TxBuffer[SendBUFFMAX];          // DMA中的串口发送缓存
uint16_t sRecv_LEN;                     // DMA的串口缓存中接收到的数据长度

static void RCC_Configuration(void)
{
    RCC_EnableAPB2PeriphClk(USARTy_GPIO_CLK | RCC_APB2_PERIPH_AFIO, ENABLE);
    RCC_EnableAPB1PeriphClk(USARTy_CLK, ENABLE);
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1, ENABLE);
    //引脚重映射
    GPIO_ConfigPinRemap(USARTy_Remap, ENABLE);
}

static void GPIO_Configuration(void)
{
    GPIO_InitType GPIO_InitStructure;

    GPIO_InitStructure.Pin = USARTy_RxPin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);
    
    GPIO_InitStructure.Pin = USARTy_TxPin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitPeripheral(USARTy_GPIO, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = WIFI_RST_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitPeripheral(WIFI_RST_GPIO, &GPIO_InitStructure);
}

static void DMA_Configuration(void)
{
    DMA_InitType DMA_InitStructure;
    DMA_DeInit(USARTy_Tx_DMA_Channel);
    // 发送通道
    DMA_InitStructure.PeriphAddr = USARTy_DMA_DR_Base;
    DMA_InitStructure.MemAddr = (uint32_t)NULL;
    DMA_InitStructure.Direction = DMA_DIR_PERIPH_DST;
    DMA_InitStructure.BufSize = 0;
    DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_BYTE;
    DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
    DMA_InitStructure.Priority = DMA_PRIORITY_VERY_HIGH;
    DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
    DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);
    DMA_ConfigInt(USARTy_Tx_DMA_Channel, DMA_INT_TXC, ENABLE);  //使能DMA发送完成中断
    DMA_ConfigInt(USARTy_Tx_DMA_Channel, DMA_INT_ERR, ENABLE);
    USART_EnableDMA(USARTy, USART_DMAREQ_TX, ENABLE);           //使能指定UART DMA
    DMA_EnableChannel(USARTy_Tx_DMA_Channel, DISABLE);          //禁用指定DMA通道

    // 接收通道
    DMA_DeInit(USARTy_Rx_DMA_Channel);
    DMA_InitStructure.PeriphAddr = USARTy_DMA_DR_Base;
    DMA_InitStructure.MemAddr = (uint32_t)TemArrRxBuffer[curTemArrIndex];
    DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
    DMA_InitStructure.BufSize = sizeof(TemArrRxBuffer[curTemArrIndex]);
    DMA_Init(USARTy_Rx_DMA_Channel, &DMA_InitStructure);
    DMA_ConfigInt(USARTy_Rx_DMA_Channel, DMA_INT_TXC, ENABLE);
    DMA_ConfigInt(USARTy_Rx_DMA_Channel, DMA_INT_ERR, ENABLE);
    USART_EnableDMA(USARTy, USART_DMAREQ_RX, ENABLE);
    DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
}

static void NVIC_Configuration(void)
{
    NVIC_InitType NVIC_InitStructure;

    // Usart3 串口中断
    NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;         // 选择中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; // 抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        // 子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                           // 根据指定的参数初始化nVIC寄存器

    /* Enable the DMA1 RX Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USARTy_DMA_Rx_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = WIFIRXDMA_IRQPrePrio;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = WIFIRXDMA_IRQSubPrio;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    /* Enable the DMA1 TX Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USARTy_DMA_Tx_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = WIFITXDMA_IRQPrePrio;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = WIFITXDMA_IRQSubPrio;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

static void BaudRate_Configuration(uint32_t USART_BaudRate)
{
    USART_InitType USART_InitStructure;
    USART_InitStructure.BaudRate = USART_BaudRate;
    USART_InitStructure.WordLength = USART_WL_8B;
    USART_InitStructure.StopBits = USART_STPB_1;
    USART_InitStructure.Parity = USART_PE_NO;
    USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
    USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
    USART_Init(USARTy, &USART_InitStructure);

    USART_ConfigInt(USARTy, USART_INT_IDLEF, ENABLE); // 开启串口空闲中断
    USART_ConfigInt(USARTy, USART_INT_ERRF, ENABLE);  // 开启串口溢出中断
    USART_Enable(USARTy, ENABLE);
}

void GPRS_DRIVER_SetATs(u32 BaudRate)
{
    USART_Enable(USARTy, DISABLE);
    DMA_EnableChannel(USARTy_Tx_DMA_Channel, DISABLE);
    DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);

    RCC_Configuration();
    GPIO_Configuration();
    DMA_Configuration();
    NVIC_Configuration();
    BaudRate_Configuration(BaudRate);
}


/**--------------------------------------------------------
 * @brief 空闲中断处理非定长数据(发完一段数据后需要暂停触发)
 *
 ---------------------------------------------------------*/
void USARTx_IRQHandler(void)
{
    OS_CPU_SR cpu_sr;
    OS_ENTER_CRITICAL(); /* Tell uC/OS-II that we are starting an ISR 		 */
    OSIntEnter();

    /* RX interrupt */
    if (USART_GetIntStatus(USARTy, USART_INT_IDLEF) == SET)
    {
        // 清除标志位
        USART_ReceiveData(USARTy); // USART3->DR;
        DMA_EnableChannel(USARTy_Rx_DMA_Channel, DISABLE);
        // 处理当前DMA内容
        SetOSFlagsForNewInform(App_Flags_NETPARSE,1<<curTemArrIndex);
        // 开始下一次dma传输
        curTemArrIndex+=1;
        if(curTemArrIndex>1) curTemArrIndex=0;
        // 计算接收缓存中的已接收到的数据数量
        sRecv_LEN = sizeof(TemArrRxBuffer[curTemArrIndex]) - DMA_GetCurrDataCounter(USARTy_Rx_DMA_Channel);
        USARTy_Rx_DMA_Channel->MADDR = (uint32_t)TemArrRxBuffer[curTemArrIndex];
        USARTy_Rx_DMA_Channel->TXNUM = sizeof(TemArrRxBuffer[curTemArrIndex]);
        // 重新使能Rx dma传输
        DMA_EnableChannel(USARTy_Rx_DMA_Channel, ENABLE);
    }

    /* Reset ORE interrupt */
    if (USART_GetIntStatus(USARTy, USART_INT_OREF) != RESET)
    {
        USART_ClrIntPendingBit(USARTy, USART_INT_OREF);
        // 把数据读走
        USART_ReceiveData(USARTy); // USART3->DR;
    }

    // Check for Noise Error (NE)
    if (USART_GetFlagStatus(USARTy, USART_FLAG_NEF) != RESET) {
        // Clear Noise Error flag
        USART_ClrFlag(USARTy, USART_FLAG_NEF);
        USART_ReceiveData(USARTy); // USART3->DR;
    }

    // Check for Parity Error (FE)
    if (USART_GetFlagStatus(USARTy, USART_FLAG_FEF) != RESET) {
        // Clear Parity Error flag
        USART_ClrFlag(USARTy, USART_FLAG_FEF);
        USART_ReceiveData(USARTy); // USART3->DR;
    }

    OSIntExit(); /* Tell uC/OS-II that we are leaving the ISR 		 */
    OS_EXIT_CRITICAL();
}

